package com.pureut.storage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pureut.common.core.exception.GlobalException;
import com.pureut.common.core.utils.bean.BeanUtils;
import com.pureut.common.datascope.annotation.DataScope;
import com.pureut.common.security.utils.DictUtils;
import com.pureut.common.security.utils.SecurityUtils;
import com.pureut.storage.domain.Warehouse;
import com.pureut.storage.dto.ReservoirAreaDto;
import com.pureut.storage.dto.WareLocationDto;
import com.pureut.storage.dto.WarehouseDto;
import com.pureut.storage.dto.WarehouseStringDto;
import com.pureut.storage.mapper.WarehouseMapper;
import com.pureut.storage.service.WarehouseService;
import com.pureut.storage.vo.WarehouseVo;
import com.pureut.system.api.FeignService;
import com.pureut.system.api.domain.SysDictData;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/***
 *
 * Author:C
 * Date:2022/12/13 17:26
 * @DESC
 */
@Service
public class WarehouseServiceImpl extends ServiceImpl<WarehouseMapper, Warehouse> implements WarehouseService {

    @Resource
    WarehouseMapper warehouseMapper;

    @Resource
    FeignService feignService;

    /**
     * 获取仓库列表
     *
     * @return
     */
    @Override
    @DataScope(deptAlias = "warehouse")
    public List<WarehouseDto> getList(WarehouseVo warehouseVo) {
        //获取仓库列表
        List<WarehouseDto> warehouse = warehouseMapper.getWarehouse2(warehouseVo);

        //获取仓库类型缓存字典数据
        List<SysDictData> array = DictUtils.getDictCache("warehouse_type");
        Map<String, String> typeMap = array.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        warehouse.forEach(e -> {
            e.setWarehouseTypeDict(typeMap.get(String.valueOf(e.getWarehouseType())));

        });
        return warehouse.stream().filter(e -> ("1").equals(e.getWarehouseType())).peek(e -> e.setChildren(getChildNode(e, warehouse))).collect(Collectors.toList());


//        for (WarehouseDto ck : warehouse) {
//            //库区列表
//            List<ReservoirAreaDto> reservoirAreaDtoList = new ArrayList<>();
//            //获取仓库下的库区
//            List<Warehouse> warehouses = warehouseMapper.selectList(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getParentCode, ck.getWarehouseCode()).eq(Warehouse::getWarehouseType, 2));
//            for (Warehouse kq : warehouses) {
//                if (ck.getWarehouseCode().equals(kq.getParentCode())) {
//                    ReservoirAreaDto reservoirAreaDto = new ReservoirAreaDto();
//                    BeanUtils.copyProperties(kq, reservoirAreaDto);
//                    reservoirAreaDto.setVolume(String.valueOf(kq.getVolume()));
//                    reservoirAreaDto.setCapacity(String.valueOf(kq.getCapacity()));
//                    reservoirAreaDto.setWarehouseType(String.valueOf(kq.getWarehouseType()));
//                    reservoirAreaDto.setWarehouseTypeDict(typeMap.get(String.valueOf(kq.getWarehouseType())));
//                    reservoirAreaDtoList.add(reservoirAreaDto);
//                }
//                ck.setChildren(reservoirAreaDtoList);
//                ck.setWarehouseTypeDict(typeMap.get(ck.getWarehouseType()));
//            }
//            //循环库区
//            for (ReservoirAreaDto kqList : reservoirAreaDtoList) {
//                //库位列表
//                List<WareLocationDto> location = new ArrayList<>();
//                //获取库区下的库位
//                List<Warehouse> kw = warehouseMapper.selectList(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getParentCode, kqList.getWarehouseCode()).eq(Warehouse::getWarehouseType, 3));
//                for (Warehouse entity : kw) {
//                    WareLocationDto wareLocationDto = new WareLocationDto();
//                    BeanUtils.copyProperties(entity, wareLocationDto);
//                    wareLocationDto.setVolume(String.valueOf(entity.getVolume()));
//                    wareLocationDto.setCapacity(String.valueOf(entity.getCapacity()));
//                    wareLocationDto.setWarehouseType(String.valueOf(entity.getWarehouseType()));
//                    wareLocationDto.setWarehouseTypeDict(typeMap.get(String.valueOf(entity.getWarehouseType())));
//                    location.add(wareLocationDto);
//                }
//                kqList.setChildren(location);
//            }
//        }
    }

    /**
     * 获取树形子节点
     *
     * @param parentNode
     * @param list
     * @return
     */
    private List<WarehouseDto> getChildNode(WarehouseDto parentNode, List<WarehouseDto> list) {
        return list.stream().filter(e -> Objects.equals(e.getParentCode(), parentNode.getWarehouseCode())).peek(e -> e.setChildren(getChildNode(e, list))).collect(Collectors.toList());
    }

    /**
     * 新增仓库
     *
     * @param warehouseVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addWarehouse(WarehouseVo warehouseVo) {
        Warehouse warehouse = new Warehouse();
        BeanUtils.copyProperties(warehouseVo, warehouse);
        warehouse.setDeptId(SecurityUtils.getDeptId());
        warehouse.setWarehouseType(Integer.parseInt(warehouseVo.getWarehouseType()));
        warehouse.setCreateBy(SecurityUtils.getUsername());
        warehouse.setCreateTime(new Date());
        warehouse.setResponsiblePerson(warehouseVo.getResponsiblePerson());
        Warehouse one = getOne(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getWarehouseCode, warehouseVo.getWarehouseCode()));
        if (one == null) {
            return save(warehouse);
        } else {
            throw new GlobalException("该编码已存在");
        }

    }

    /**
     * 修改仓库
     *
     * @param warehouseVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateWarehouse(WarehouseVo warehouseVo) {
        Warehouse warehouse = getById(warehouseVo.getId());
        if (warehouse.getWarehouseType() == 1) {
            warehouse.setResponsiblePerson(warehouseVo.getResponsiblePerson());
        }
        warehouse.setWarehouseName(warehouseVo.getWarehouseName());
        warehouse.setVolume(warehouseVo.getVolume());
        warehouse.setCapacity(warehouseVo.getCapacity());
//        warehouse.setBadArea(warehouseVo.getBadArea());
        warehouse.setRemark(warehouseVo.getRemark());
        return updateById(warehouse);
    }

    /**
     * 查看
     *
     * @return
     */
    @Override
    public WarehouseDto getView(Long id) {
        List<SysDictData> array = DictUtils.getDictCache("warehouse_type");
        Map<String, String> typeMap = array.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        WarehouseDto warehouseDto = new WarehouseDto();
        Warehouse warehouse = getById(id);
        if (warehouse == null) {
            return null;
        }
        if (warehouse.getResponsiblePerson() != 0) {
            //获取用户名称
            long userId = warehouse.getResponsiblePerson();
            String userName = feignService.getUserName(userId);
            warehouseDto.setUserName(userName);
            warehouseDto.setResponsiblePerson(warehouse.getResponsiblePerson());
        }
        BeanUtils.copyProperties(warehouse, warehouseDto);
        warehouseDto.setCapacity(String.valueOf(warehouse.getCapacity()));
        warehouseDto.setVolume(String.valueOf(warehouse.getVolume()));
        warehouseDto.setWarehouseType(String.valueOf(warehouse.getWarehouseType()));
        warehouseDto.setWarehouseTypeDict(typeMap.get(String.valueOf(warehouse.getWarehouseType())));
        return warehouseDto;
    }

    /**
     * 删除仓库
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteWarehouse(Integer id) {
        //判断该仓库下是否有子区域信息
        Warehouse warehouse = getById(id);
        List<Warehouse> warehouses = warehouseMapper.selectList(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getParentCode, warehouse.getWarehouseCode()));
        if (warehouses.size() == 0) {
            return removeById(warehouse);
        } else {
            throw new GlobalException("存在子区域，请先删除子区域");
        }
        //TODO 判断库位是否有绑定的物料信息
    }

    /**
     * 新增子区域
     *
     * @param warehouseVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addSubarea(WarehouseVo warehouseVo) {
        //如果是单体新增
        if ("1".equals(warehouseVo.getAddType())) {
            Warehouse byId = getById(warehouseVo.getId());
            Warehouse warehouse = new Warehouse();
            BeanUtils.copyProperties(warehouseVo, warehouse);
            warehouse.setWarehouseType(Integer.parseInt(warehouseVo.getWarehouseType()));
            warehouse.setCreateBy(SecurityUtils.getUsername());
            warehouse.setCreateTime(new Date());
            if (byId.getBadArea() == 1) {
                warehouse.setBadArea(1);
            } else {
                warehouse.setBadArea(2);
            }
            //验证编码是否唯一
            Warehouse one = getOne(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getWarehouseCode, warehouseVo.getWarehouseCode()));
            if (one == null) {
                return save(warehouse);
            } else {
                throw new GlobalException("该编码已经存在");
            }
        } else {
            Warehouse byId = getById(warehouseVo.getId());
            List<Warehouse> warehouses = new ArrayList<>();
            //多个新增
            for (int i = 0; i <= warehouseVo.getNumber() - 1; i++) {
                Warehouse warehouse = new Warehouse();
                if (i == 0) {
                    BeanUtils.copyProperties(warehouseVo, warehouse);
                    warehouse.setWarehouseType(Integer.parseInt(warehouseVo.getWarehouseType()));
                    warehouse.setWarehouseCode(warehouseVo.getCodePrefix() + warehouseVo.getStartCode());
                    warehouse.setWarehouseName(warehouseVo.getWarehouseName() + warehouseVo.getStartCode());
                    warehouse.setCreateBy(SecurityUtils.getUsername());
                    warehouse.setCreateTime(new Date());
                    if (byId.getBadArea() == 1) {
                        warehouse.setBadArea(1);
                    } else {
                        warehouse.setBadArea(2);
                    }
                    //验证编码是否唯一
                    Warehouse one = getOne(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getWarehouseCode, warehouse.getWarehouseCode()));
                    if (one == null) {
                        warehouses.add(warehouse);
                    } else {
                        throw new GlobalException("存在重复的编码");
                    }

                } else {
                    BeanUtils.copyProperties(warehouseVo, warehouse);
                    warehouse.setWarehouseType(Integer.parseInt(warehouseVo.getWarehouseType()));
                    warehouse.setWarehouseCode(addOne(warehouses.get(i - 1).getWarehouseCode()));
                    String s = addOne(warehouses.get(i - 1).getWarehouseCode());
                    String[] split = s.split("[^0-9]");
                    String numStr = split[split.length - 1];
                    warehouse.setWarehouseName(warehouseVo.getWarehouseName() + numStr);
                    warehouse.setCreateBy(SecurityUtils.getUsername());
                    warehouse.setCreateTime(new Date());
                    if (byId.getBadArea() == 1) {
                        warehouse.setBadArea(1);
                    } else {
                        warehouse.setBadArea(2);
                    }
                    //验证编码是否唯一
                    Warehouse one = getOne(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getWarehouseCode, warehouse.getWarehouseCode()));
                    if (one == null) {
                        warehouses.add(warehouse);
                    } else {
                        throw new GlobalException("存在重复的编码");
                    }

                }
            }
            return saveBatch(warehouses);
        }
    }

    /**
     * 根据库位编码获取仓库-库区-库位
     *
     * @param warehouseCode
     * @return
     */
    @Override
    public WarehouseStringDto getWarehouseCode(String warehouseCode) {
        WarehouseStringDto warehouseStringDto = new WarehouseStringDto();
        //库位4
        Warehouse warehouseKw = warehouseMapper.selectOne(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getWarehouseCode, warehouseCode));
        if (warehouseKw == null) {
            return warehouseStringDto;
        }
        //库区3
        List<Warehouse> warehouseKq = warehouseMapper.selectList(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getWarehouseCode, warehouseKw.getParentCode()).eq(Warehouse::getWarehouseType, 3));
        //仓库2
        List<Warehouse> warehouseCk = warehouseMapper.selectList(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getWarehouseCode, warehouseKq.get(0).getParentCode()).eq(Warehouse::getWarehouseType, 2));
        //1
        List<Warehouse> warehouseCkOne = warehouseMapper.selectList(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getWarehouseCode, warehouseKq.get(0).getParentCode()).eq(Warehouse::getWarehouseType, 1));
        warehouseStringDto.setCkId(warehouseCkOne.get(0).getId());
        warehouseStringDto.setKqId(warehouseCk.get(0).getId());
        warehouseStringDto.setKwId(warehouseKq.get(0).getId());
        warehouseStringDto.setHjId(warehouseKw.getId());
        warehouseStringDto.setCombinationName(warehouseCkOne.get(0).getWarehouseName() + "-" + warehouseCk.get(0).getWarehouseName() + "-" + warehouseKq.get(0).getWarehouseName() + "-" + warehouseKw.getWarehouseName());
        return warehouseStringDto;
    }

    /**
     * 获取仓库-库区-库位列表
     *
     * @return
     */
    @Override
    public List<String> getCombinationWarehouse() {
        //创建返回结果集
        List<String> result = new ArrayList<>();
        //获取仓库
        List<Warehouse> warehouseCk = warehouseMapper.selectList(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getWarehouseType, 1));

        for (Warehouse ck : warehouseCk) {
            //获取仓库下的库区
            List<Warehouse> warehouseKq = warehouseMapper.selectList(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getParentCode, ck.getWarehouseCode()).eq(Warehouse::getWarehouseType, 2));
            //获取库区下的库位
            for (Warehouse kq : warehouseKq) {
                List<Warehouse> warehouseKw = warehouseMapper.selectList(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getParentCode, kq.getWarehouseCode()).eq(Warehouse::getWarehouseType, 3));
                for (Warehouse kw : warehouseKw) {
                    //获取库位下的货架
                    List<Warehouse> warehouseHJ = warehouseMapper.selectList(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getParentCode, kq.getWarehouseCode()).eq(Warehouse::getWarehouseType, 4));
                    for (Warehouse hj : warehouseHJ) {
                        String combinationName = ck.getWarehouseName() + "-" + kq.getWarehouseName() + "-" + kw.getWarehouseName() + "-" + hj.getWarehouseName();
                        result.add(combinationName);
                    }
                }
            }
        }

//        for (Warehouse ck : warehouseCk) {
//            //获取仓库下的库区
//            List<Warehouse> warehouseKq = warehouseMapper.selectList(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getParentCode, ck.getWarehouseCode()).eq(Warehouse::getWarehouseType, 2));
//            //获取库区下的库位
//            for (Warehouse kq : warehouseKq) {
//                List<Warehouse> warehouseKw = warehouseMapper.selectList(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getParentCode, kq.getWarehouseCode()).eq(Warehouse::getWarehouseType, 3));
//                for (Warehouse kw : warehouseKw) {
//                    String combinationName = ck.getWarehouseName() + "-" + kq.getWarehouseName() + "-" + kw.getWarehouseName();
//                    result.add(combinationName);
//                }
//            }
//        }
        return result;
    }

    /**
     * 获取仓库
     *
     * @return
     */
    @Override
    public List<WarehouseDto> getCkById() {
        WarehouseVo warehouseVo = new WarehouseVo();
        return warehouseMapper.getWarehouse(warehouseVo);
    }


    /**
     * 字符串末尾数字加1
     *
     * @param testStr
     * @return
     */
    public String addOne(String testStr) {
        //根据不是数字的字符拆分字符串
        String[] strs = testStr.split("[^0-9]");
        //取出最后一组数字
        String numStr = strs[strs.length - 1];
        //如果最后一组没有数字(也就是不以数字结尾)，抛NumberFormatException异常
        if (numStr != null && numStr.length() > 0) {
            //取出字符串的长度
            int n = numStr.length();
            //将该数字加一
            int num = Integer.parseInt(numStr) + 1;
            String added = String.valueOf(num);
            n = Math.min(n, added.length());
            //拼接字符串
            return testStr.subSequence(0, testStr.length() - n) + added;
        } else {
            throw new NumberFormatException();
        }
    }

}
